package lion.mail;

import java.security.Security;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;

import org.apache.commons.lang.StringUtils;

/**
 * 邮件发送器
 *
 * @author lion
 * @date 2011-5-26
 */
@SuppressWarnings("restriction")
public class JMailSender {

	private String server;
	private String userName;
	private String password;
	private boolean debug = false;
	private Session session;
	private Transport transport;
	private int port = 25;
	private boolean ssl = false;
	private String proxyHost = null;
	private int proxyPort;

	static {
		Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
	}

	public JMailSender send(MailBuilder mailBuilder) throws Exception {

		if (session == null) {
			createSession();
		}
		mailBuilder.setSession(session);
		if (transport == null || !transport.isConnected()) {
			transport = session.getTransport("smtp");
			transport.connect(server, userName, password);
		}

		Message msg = mailBuilder.getMessage();
		transport.sendMessage(mailBuilder.getMessage(), msg.getAllRecipients());

		return this;
	}

	/**
	 * close the Transport Connection
	 */
	public void done() {

		if (this.transport != null && this.transport.isConnected()) {
			try {
				this.transport.close();
			} catch (MessagingException e) {
			}
		}
		transport = null;
	}

	private void createSession() {

		Properties props = new Properties();

		if (StringUtils.isNotBlank(proxyHost)) {
			props.put("proxySet", "true");
			props.put("socksProxyHost", proxyHost);
			props.put("socksProxyPort", proxyPort);
		}

		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.host", server);
		props.put("mail.smtp.port", this.port);
		props.put("mail.smtp.auth.ntlm.disable", true);

		if (this.ssl) {
			props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
			props.put("mail.smtp.socketFactory.fallback", "false");
			props.put("mail.smtp.socketFactory.port", this.port);
		}

		session = Session.getInstance(props, new Authenticator() {

			@Override
			protected PasswordAuthentication getPasswordAuthentication() {

				return new PasswordAuthentication(userName, password);
			}
		});
		session.setDebug(debug);
	}

	public void setDebug(boolean debug) {

		this.debug = debug;
	}

	public String getServer() {

		return server;
	}

	public void setServer(String server) {

		this.server = server;
	}

	public String getUserName() {

		return userName;
	}

	public void setUserName(String userName) {

		this.userName = userName;
	}

	public String getPassword() {

		return password;
	}

	public void setPassword(String password) {

		this.password = password;
	}

	public void setSession(Session session) {

		this.session = session;
	}

	public int getPort() {

		return port;
	}

	public void setPort(int port) {

		this.port = port;
	}

	public boolean isSsl() {

		return ssl;
	}

	public void setSsl(boolean ssl) {

		this.ssl = ssl;
	}

	public void setProxy(String host, int port) {

		this.proxyHost = host;
		this.proxyPort = port;
	}

}
